﻿using System;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;

using AjaxControlToolkit;
using System.Web.Script.Serialization;

[assembly: WebResource("SCS.Web.UI.WebControls.Dialogs.DialogControl.js", "text/javascript")]
[assembly: WebResource("SCS.Web.UI.WebControls.Dialogs.DialogControl.debug.js", "text/javascript")]

[assembly: WebResource("SCS.Web.UI.WebControls.Dialogs.DialogControl.debug.js", "text/javascript")]
[assembly: WebResource("SCS.Web.UI.WebControls.Dialogs.close.gif", "image/gif")]

namespace SCS.Web.UI.WebControls.Dialogs
{
    /// <summary>
    /// Represents a client-side dialog.
    /// </summary>
    /// <seealso cref="SearchDialog"/>
    [RequiredScript(typeof(ModalPopupExtender), 1)]
    [RequiredScript(typeof(DialogExtender), 2)]
    [ClientScriptResource("SCS.DialogControl", "SCS.Web.UI.WebControls.Dialogs.DialogControl.js", LoadOrder = 3)]
    public class Dialog : ScriptControlBase
    {
        private enum DialogShowMode { UpdateNothing, UpdateTitle, UpdateContent, UpdateTitleAndContent }

        #region Fields

        private Dictionary<string, object> _dialopProps = null;
        private Dictionary<string, object> _clientStates = null;

        private Dictionary<string, string> _servicePassThroughData;

        private DialogShowMode _partialPostbackShowMode;

        #endregion

        /// <summary>
        /// Initializes a new instance of the <see cref="Dialog"/> class.
        /// </summary>
        public Dialog() : base(true, HtmlTextWriterTag.Div)
        {
            ClientStateCollection["show"] = false;
        }

        /// <summary>
        /// Shows the dialog.
        /// </summary>
        public virtual void Show()
        {
            _partialPostbackShowMode = DialogShowMode.UpdateNothing;
            ClientStateCollection["show"] = true;
        }

        /// <summary>
        /// Shows the dialog with the specified title.
        /// </summary>
        /// <param name="title">The dialog title.</param>
        public virtual void Show(string title)
        {
            Title = title;

            _partialPostbackShowMode = DialogShowMode.UpdateTitle;
            ClientStateCollection["show"] = true;
        }

        /// <summary>
        /// Shows the dialog with the specified title and body content.
        /// </summary>
        /// <param name="title">The title.</param>
        /// <param name="content">The body content.</param>
        public virtual void Show(string title, string content)
        {
            Content = content;
            Title = title;

            Enabled = true;

            _partialPostbackShowMode = DialogShowMode.UpdateTitleAndContent;
            ClientStateCollection["show"] = true;
        }

        /// <summary>
        /// Raises the <see cref="E:Load"/> event.
        /// </summary>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
        }

        /// <summary>
        /// Raises the <see cref="E:PreRender"/> event.
        /// </summary>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);

            DialogPropertyCollection.Add("id", ModalPopupBehaviorId);
            DialogPropertyCollection.Add("PopupControlID", ClientID);
            DialogPropertyCollection.Add("dynamicControlID", ClientID + "_content");
            DialogPropertyCollection.Add("CancelControlID", ClientID + "_close_top");

            if (X > -1)
                DialogPropertyCollection.Add("X", X);

            if (Y > -1)
                DialogPropertyCollection.Add("Y", Y);

            if (!string.IsNullOrEmpty(BackgroundCssClass))
                DialogPropertyCollection.Add("BackgroundCssClass", BackgroundCssClass);

            if (AllowDrag)
                DialogPropertyCollection.Add("PopupDragHandleControlID", ClientID + "_top");

            if (!string.IsNullOrEmpty(ContentServicePath))
                DialogPropertyCollection.Add("dynamicServicePath", ContentServicePath);

            if (!string.IsNullOrEmpty(ContentServiceMethod))
                DialogPropertyCollection.Add("dynamicServiceMethod", ContentServiceMethod);

            if (!string.IsNullOrEmpty(ContentContextKey))
                DialogPropertyCollection.Add("dynamicContextKey", ContentContextKey);

            if (RepositionMode != ModalPopupRepositionMode.RepositionOnWindowResizeAndScroll)
                DialogPropertyCollection.Add("repositionMode", RepositionMode);

            if (!string.IsNullOrEmpty(OnOkScript))
                DialogPropertyCollection.Add("OnOkScript", OnOkScript);

            if (!string.IsNullOrEmpty(OnCancelScript))
                DialogPropertyCollection.Add("OnCancelScript", OnCancelScript);

            if (ShowOkButton)
                DialogPropertyCollection.Add("OkControlID", ClientID + "_ok");

            //DialogPropertyCollection.Add("DropShadown", true);

            if ((bool)ClientStateCollection["show"] && AjaxHelper.IsInAsyncPostBack(Page) && !AjaxHelper.IsControlInPartialRendering(this))
            {
                WritePartialPostbackShowClientCode();
            }

            Visible = Enabled;
        }

        /// <summary>
        /// Outputs the content of a server control's children to a provided <see cref="T:System.Web.UI.HtmlTextWriter"/> object, which writes the content to be rendered on the client.
        /// </summary>
        /// <param name="writer">The <see cref="T:System.Web.UI.HtmlTextWriter"/> object that receives the rendered content.</param>
        protected override void RenderChildren(HtmlTextWriter writer)
        {
            // write panel for title and close button            
            writer.AddAttribute(HtmlTextWriterAttribute.Id, ClientID + "_top");
            writer.AddAttribute(HtmlTextWriterAttribute.Class, "top");
            writer.RenderBeginTag(HtmlTextWriterTag.Div);

            // write title
            writer.AddAttribute(HtmlTextWriterAttribute.Class, "title");
            writer.AddAttribute(HtmlTextWriterAttribute.Title, ToolTip);
            writer.RenderBeginTag(HtmlTextWriterTag.H1);

            // write anchor to set focus to when dialog is shown for accessibility purposes
            writer.AddAttribute(HtmlTextWriterAttribute.Id, ClientID + "_caption");
            writer.RenderBeginTag(HtmlTextWriterTag.A);
            writer.Write(Title);
            writer.RenderEndTag(); // close anchor               

            writer.RenderEndTag(); // close h1 tag

            // write close button

            writer.AddAttribute(HtmlTextWriterAttribute.Id, ClientID + "_close_top");
            writer.AddAttribute(HtmlTextWriterAttribute.Class, "close");
            writer.AddAttribute(HtmlTextWriterAttribute.Alt, CloseButtonToolTip);

            if (!string.IsNullOrEmpty(CloseButtonText) && string.IsNullOrEmpty(CloseButtonImage))
            {
                writer.AddAttribute(HtmlTextWriterAttribute.Type, "button");
                writer.AddAttribute(HtmlTextWriterAttribute.Value, CloseButtonText);
            }
            else
            {
                writer.AddAttribute(HtmlTextWriterAttribute.Type, "image");

                string url = (!string.IsNullOrEmpty(CloseButtonImage))
                                ? Page.ResolveClientUrl(CloseButtonImage)
                                : Page.ClientScript.GetWebResourceUrl(typeof(Dialog), "SCS.Web.UI.WebControls.Dialogs.close.gif");
                
                writer.AddAttribute(HtmlTextWriterAttribute.Src, url);
            }

            writer.RenderBeginTag(HtmlTextWriterTag.Input);
            writer.RenderEndTag();

            writer.RenderEndTag(); // close top div                

            // write main content area
            writer.AddAttribute(HtmlTextWriterAttribute.Id, ClientID + "_content");
            writer.AddAttribute(HtmlTextWriterAttribute.Class, "body");
            writer.RenderBeginTag(HtmlTextWriterTag.Div);

            RenderDialogContent(writer);

            writer.RenderEndTag(); // close write main content area

            writer.AddAttribute(HtmlTextWriterAttribute.Class, "bottom");
            writer.RenderBeginTag(HtmlTextWriterTag.Div);

            RenderDialogFooter(writer);

            writer.RenderEndTag(); // close footer controls
        }

        /// <summary>
        /// Renders the content of the dialog.
        /// </summary>
        /// <param name="writer">The writer.</param>
        protected virtual void RenderDialogContent(HtmlTextWriter writer)
        {
            writer.Write(Content);
        }

        /// <summary>
        /// Renders the content of the dialog.
        /// </summary>
        /// <param name="writer">The writer.</param>
        protected virtual void RenderDialogFooter(HtmlTextWriter writer)
        {
            if (ShowOkButton)
            {
                writer.AddAttribute(HtmlTextWriterAttribute.Type, "button");
                writer.AddAttribute(HtmlTextWriterAttribute.Value, "OK");
                writer.AddAttribute(HtmlTextWriterAttribute.Id, ClientID + "_ok");
                writer.RenderBeginTag(HtmlTextWriterTag.Input);
                writer.RenderEndTag();
            }

            if (ShowCloseButton)
            {
                writer.AddAttribute(HtmlTextWriterAttribute.Type, "button");
                writer.AddAttribute(HtmlTextWriterAttribute.Value, "Close");
                writer.AddAttribute(HtmlTextWriterAttribute.Id, ClientID + "_close");
                writer.RenderBeginTag(HtmlTextWriterTag.Input);
                writer.RenderEndTag();
            }
        }

        /// <summary>
        /// Loads the client state from the browser.
        /// </summary>
        /// <param name="clientState">State of the client.</param>
        protected override void LoadClientState(string clientState)
        {
            clientState = clientState.TrimStart('{').TrimEnd('}');

            foreach (string keyValue in clientState.Split(','))
            {
                string[] pair = keyValue.Split(':');

                if (pair.Length > 1)
                {
                    pair[0] = pair[0].Trim();
                    pair[1] = pair[1].Trim();

                    object val;

                    if (pair[1].StartsWith("\"") && pair[1].EndsWith("\""))
                    {
                        pair[1] = pair[1].Substring(1, pair[1].Length - 2);

                        DateTime dateVal;

                        if (DateTime.TryParse(pair[1], out dateVal))
                        {
                            val = dateVal;
                        }
                        else
                        {
                            if (pair[1].Length == 1)
                            {
                                val = pair[1].ToCharArray()[0];
                            }
                            else
                            {
                                val = pair[1];
                            }
                        }
                    }
                    else
                    {
                        int intVal;

                        if (int.TryParse(pair[1], out intVal))
                        {
                            val = intVal;
                        }
                        else
                        {
                            bool boolVal;

                            if (bool.TryParse(pair[1], out boolVal))
                            {
                                val = boolVal;
                            }
                            else
                            {
                                val = pair[1];
                            }
                        }
                    }

                    string key = pair[0].TrimStart('\"').TrimEnd('\"');

                    if (ClientStateCollection.ContainsKey(key))
                    {
                        ClientStateCollection[key] = val;
                    }
                    else
                    {
                        ClientStateCollection.Add(key, val);
                    }
                }
            }
        }

        /// <summary>
        /// Saves the client state from the browser.
        /// </summary>
        /// <returns></returns>
        protected override string SaveClientState()
        {
            StringBuilder state = new StringBuilder(128);
            state.Append("{");

            foreach (KeyValuePair<string, object> pair in ClientStateCollection)
            {
                object value = pair.Value;
                string valueParam = "";

                if (value is string || value is char || value is DateTime)
                {
                    valueParam = string.Format(@"""{0}""", value);
                }
                else if (value is bool)
                {
                    valueParam = value.ToString().ToLower();
                }
                else
                {
                    valueParam = value.ToString();
                }

                state.AppendFormat(@"""{0}"": {1}, ", pair.Key, valueParam);
            }

            state.Remove(state.Length - 2, 2);
            state.Append("}");

            return state.ToString();
        }

        /// <summary>
        /// Finds a control by Id.
        /// </summary>
        /// <param name="id">The control Id.</param>
        /// <returns>A matching control; or, <c>null</c> if not found.</returns>
        internal Control FindPageControl(string id)
        {
            Control c = Page.FindControl(id);
            Control nc = NamingContainer;

            while ((null == c) && (null != nc))
            {
                c = nc.FindControl(id);
                nc = nc.NamingContainer;
            }

            return c;
        }

        /// <summary>
        /// Writes the show client code when executing under an partial post-back.
        /// </summary>
        private void WritePartialPostbackShowClientCode()
        {
            List<object> additionalArguments = GetAdditionalShowArguments();

            // show dialog and make sure it is shown on this postback only

            string js = @"
                Sys.Application.add_load(dialogLoader);

                function dialogLoader() {{                    
                    var dialog = $find('{0}');
                    dialog.show({1}, {2}{3});
                    Sys.Application.remove_load(dialogLoader);    
                }};";

            string content = (_partialPostbackShowMode == DialogShowMode.UpdateContent || _partialPostbackShowMode == DialogShowMode.UpdateTitleAndContent)
                ? string.Format("'{0}'", AjaxHelper.EscapeQuotes(Content)) : "null";

            string title = (_partialPostbackShowMode == DialogShowMode.UpdateTitle || _partialPostbackShowMode == DialogShowMode.UpdateTitleAndContent)
                ? string.Format("'{0}'", AjaxHelper.EscapeQuotes(Title)) : "null";

            string extendedArgs = "";

            foreach (object o in additionalArguments)
            {
                if (o is string)
                {
                    extendedArgs += string.Format(", '{0}'", AjaxHelper.EscapeQuotes((string)o));
                }
                else
                {
                    extendedArgs += string.Format(", {0}", o);
                }
            }

            js = string.Format(js, this.ClientID, title, content, extendedArgs);

            string key = string.Format("{0}_ShowCode", this.ID);

            ToolkitScriptManager.RegisterStartupScript(Page, typeof(Page), key, js, true);
        }

        /// <summary>
        /// Gets additional function arguments for showing dialog.
        /// </summary>
        /// <returns>A list of additional function arguments.</returns>
        protected virtual List<object> GetAdditionalShowArguments()
        {
            return new List<object>();
        }

        /// <summary>
        /// Adds or updates data key/values to be passed on to the service method.
        /// </summary>
        /// <param name="key">The data key.</param>
        /// <param name="value">The data value.</param>
        public void AddOrUpdateServicePassThruData(string key, string value)
        {
            if (ServicePassThruData.ContainsKey(key))
                ServicePassThruData[key] = value;
            else
                ServicePassThruData.Add(key, value);
        }

        #region Properties

        protected override HtmlTextWriterTag TagKey
        {
            get
            {
                return HtmlTextWriterTag.Div;
            }
        }

        #region Appearance

        /// <summary>
        /// Gets or sets the title.
        /// </summary>
        /// <value>The title.</value>
        [Category("Appearance"), DefaultValue(""), Bindable(true), Themeable(false)]
        [PersistenceMode(PersistenceMode.Attribute), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), NotifyParentProperty(true)]
        public virtual string Title
        {
            get
            {
                object o = ViewState["Title"];

                if (o != null)
                    return (string)o;

                return "";
            }
            set
            {
                ViewState["Title"] = value;
            }
        }

        /// <summary>
        /// Gets or sets the body content.
        /// </summary>
        /// <value>The body content.</value>
        [Category("Appearance"), DefaultValue(""), Bindable(true), Themeable(false)]
        [PersistenceMode(PersistenceMode.Attribute), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), NotifyParentProperty(true)]
        public virtual string Content
        {
            get
            {
                object o = ViewState["Content"];

                if (o != null)
                    return (string)o;

                return "";
            }
            set
            {
                ViewState["Content"] = value;
            }
        }

        /// <summary>
        /// Gets or sets the title bar close button text.
        /// </summary>
        /// <value>The title bar close button text.</value>
        [Category("Appearance"), DefaultValue(""), Description(""), Bindable(false), Themeable(true)]
        [PersistenceMode(PersistenceMode.Attribute), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), NotifyParentProperty(true)]
        public virtual string CloseButtonText
        {
            get
            {
                object o = ViewState["TitleBarCloseButtonText"];

                if (o != null)
                    return (string)o;

                return "";
            }
            set
            {
                ViewState["TitleBarCloseButtonText"] = value;
            }
        }

        /// <summary>
        /// Gets or sets the title bar close button tool tip.
        /// </summary>
        /// <value>The title bar close button tool tip.</value>
        [Category("Appearance"), Description("Close"), Bindable(false), Themeable(false)]
        [PersistenceMode(PersistenceMode.Attribute), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), NotifyParentProperty(true)]
        public virtual string CloseButtonToolTip
        {
            get
            {
                object o = ViewState["TitleBarCloseButtonToolTip"];

                if (o != null)
                    return (string)o;

                return "Close";
            }
            set
            {
                ViewState["TitleBarCloseButtonToolTip"] = value;
            }
        }

        /// <summary>
        /// Gets or sets the title bar close button image.
        /// </summary>
        /// <value>The title bar close button image.</value>
        [UrlProperty]
        [EditorAttribute(typeof(System.Web.UI.Design.UrlEditor), typeof(System.Drawing.Design.UITypeEditor))]
        [Category("Appearance"), DefaultValue(""), Description(""), Bindable(false), Themeable(true)]
        [PersistenceMode(PersistenceMode.Attribute), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), NotifyParentProperty(true)]
        public virtual string CloseButtonImage
        {
            get
            {
                object o = ViewState["TitleBarCloseButtonImage"];

                if (o != null)
                    return (string)o;

                return "";
            }
            set
            {
                ViewState["TitleBarCloseButtonImage"] = value;
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether to show the OK button.
        /// </summary>
        /// <value><c>true</c> if showing ok button; otherwise, <c>false</c>.</value>
        [Category("Appearance"), DefaultValue(false), Description(""), Bindable(false), Themeable(true)]
        [PersistenceMode(PersistenceMode.Attribute), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), NotifyParentProperty(true)]
        public virtual bool ShowOkButton
        {
            get
            {
                object o = ViewState["ShowOkButton"];

                if (o != null)
                    return (bool)o;

                return false;
            }
            set
            {
                ViewState["ShowOkButton"] = value;
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether to show the Close button.
        /// </summary>
        /// <value><c>true</c> if showing close button; otherwise, <c>false</c>.</value>
        [Category("Appearance"), DefaultValue(false), Description(""), Bindable(false), Themeable(true)]
        [PersistenceMode(PersistenceMode.Attribute), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), NotifyParentProperty(true)]
        public virtual bool ShowCloseButton
        {
            get
            {
                object o = ViewState["ShowCancelButton"];

                if (o != null)
                    return (bool)o;

                return false;
            }
            set
            {
                ViewState["ShowCancelButton"] = value;
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether to show the titlebar's Close button.
        /// </summary>
        /// <value><c>true</c> if showing close button; otherwise, <c>false</c>.</value>
        [Category("Appearance"), DefaultValue(true), Bindable(true), Themeable(false)]
        [PersistenceMode(PersistenceMode.Attribute), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), NotifyParentProperty(true)]
        public virtual bool ShowTitlebarCloseButton
        {
            get
            {
                object o = ViewState["ShowCloseButton"];

                if (o != null)
                    return (bool)o;

                return true;
            }
            set
            {
                ViewState["ShowCloseButton"] = value;
            }
        }

        [Category("Appearance")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), PersistenceMode(PersistenceMode.Attribute), NotifyParentProperty(true)]
        public virtual string BackgroundCssClass
        {
            get
            {
                object o = ViewState["BackgroundCssClass"];

                if (o != null)
                    return (string)o;

                return "";
            }
            set
            {
                ViewState["BackgroundCssClass"] = value;
            }
        }

        #endregion

        #region Dynamic Populate

        /// <summary>
        /// Gets or sets the service path.
        /// </summary>
        /// <value>The service path.</value>        
        [UrlProperty]
        [TypeConverter(typeof(ServicePathConverter))]
        [Category("Dynamic Populate"), Description(""), Bindable(true), Themeable(false)]
        [PersistenceMode(PersistenceMode.Attribute), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), NotifyParentProperty(true)]
        public virtual string ContentServicePath
        {
            get
            {
                object o = ViewState["ContentServicePath"];

                if (o != null)
                    return (string)o;

                return string.Empty;
            }
            set
            {
                ViewState["ContentServicePath"] = value;
            }
        }

        /// <summary>
        /// Gets or sets the service method.
        /// </summary>
        /// <value>The service method.</value>
        [Category("Dynamic Populate"), DefaultValue(""), Description(""), Bindable(true), Themeable(false)]
        [PersistenceMode(PersistenceMode.Attribute), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), NotifyParentProperty(true)]
        public virtual string ContentServiceMethod
        {
            get
            {
                object o = ViewState["ContentServiceMethod"];

                if (o != null)
                    return (string)o;

                return string.Empty;
            }
            set
            {
                ViewState["ContentServiceMethod"] = value;
            }
        }

        /// <summary>
        /// Gets or sets the context key passed on to the service.
        /// </summary>
        /// <value>The context key passed on to the service.</value>
        [Category("Dynamic Populate"), DefaultValue(""), Description(""), Bindable(true), Themeable(false)]
        [PersistenceMode(PersistenceMode.Attribute), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), NotifyParentProperty(true)]
        public virtual string ContentContextKey
        {
            get
            {
                object o = ViewState["DynamicContextKey"];

                if (o != null)
                    return (string)o;

                return string.Empty;
            }
            set
            {
                ViewState["DynamicContextKey"] = value;
            }
        }

        [ExtenderControlProperty]
        [ClientPropertyName("contentUrl")]
        [Category("Dynamic Populate"), DefaultValue(""), Description(""), Bindable(true), Themeable(false)]
        [PersistenceMode(PersistenceMode.Attribute), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), NotifyParentProperty(true)]
        public virtual string ContentUrl
        {
            get
            {
                object o = ViewState["ContentUrl"];

                if (o != null)
                    return (string)o;

                return string.Empty;
            }
            set
            {
                ViewState["ContentUrl"] = value;
            }
        }

        #endregion

        #region Behavior

        /// <summary>
        /// Gets or sets the target control id.
        /// </summary>
        /// <value>The target control id.</value>
        [ExtenderControlProperty]
        [ClientPropertyName("targetControlId")]
        [Category("Behavior"), DefaultValue(""), Bindable(true), Themeable(false)]
        [PersistenceMode(PersistenceMode.Attribute), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), NotifyParentProperty(true)]
        [IDReferenceProperty(typeof(WebControl))]
        public virtual string TargetControlId
        {
            get
            {
                object o = ViewState["TargetControlId"];

                if (o != null)
                    return (string)o;

                return string.Empty;
            }
            set
            {
                ViewState["TargetControlId"] = value;
            }
        }

        /// <summary>
        /// Gets or sets the X coordinate of the dialog.
        /// </summary>
        /// <value>The X coordinate of the dialog.</value>
        [Category("Behavior"), DefaultValue(-1), Bindable(true), Themeable(true)]
        [PersistenceMode(PersistenceMode.Attribute), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), NotifyParentProperty(true)]
        public virtual int X
        {
            get
            {
                object o = ViewState["X"];

                if (o != null)
                    return (int)o;

                return -1;
            }
            set
            {
                ViewState["X"] = value;
            }
        }

        /// <summary>
        /// Gets or sets the Y coordinate of the dialog..
        /// </summary>
        /// <value>The Y coordinate of the dialog.</value>
        [Category("Behavior"), DefaultValue(-1), Bindable(true), Themeable(true)]
        [PersistenceMode(PersistenceMode.Attribute), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), NotifyParentProperty(true)]
        public virtual int Y
        {
            get
            {
                object o = ViewState["Y"];

                if (o != null)
                    return (int)o;

                return -1;
            }
            set
            {
                ViewState["Y"] = value;
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether dialog can be moved.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if dialog can be moved; otherwise, <c>false</c>.
        /// </value>
        [Category("Behavior")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), PersistenceMode(PersistenceMode.Attribute), NotifyParentProperty(true)]
        public virtual bool AllowDrag
        {
            get
            {
                object o = ViewState["AllowDrag"];

                if (o != null)
                    return (bool)o;

                return true;
            }
            set
            {
                ViewState["AllowDrag"] = value;
            }
        }

        /// <summary>
        /// Gets or sets the reposition mode.
        /// </summary>
        /// <value>The reposition mode.</value>
        [Category("Behavior")]
        [DefaultValue(ModalPopupRepositionMode.RepositionOnWindowResizeAndScroll)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), PersistenceMode(PersistenceMode.Attribute), NotifyParentProperty(true)]
        public ModalPopupRepositionMode RepositionMode
        {
            get
            {
                object o = ViewState["RepositionMode"];

                if (o != null)
                    return (ModalPopupRepositionMode)o;

                return ModalPopupRepositionMode.RepositionOnWindowResizeAndScroll;
            }
            set
            {
                ViewState["RepositionMode"] = value;
            }
        }

        #endregion

        #region Scripting

        [Category("Scripting")]
        [DefaultValue("")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), PersistenceMode(PersistenceMode.Attribute), NotifyParentProperty(true)]
        public virtual string OnOkScript
        {
            get
            {
                object o = ViewState["OnOkScript"];

                if (o != null)
                    return (string)o;

                return "";
            }
            set
            {
                ViewState["OnOkScript"] = value;
            }
        }

        [Category("Scripting")]
        [DefaultValue("")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), PersistenceMode(PersistenceMode.Attribute), NotifyParentProperty(true)]
        public virtual string OnCancelScript
        {
            get
            {
                object o = ViewState["OnCancelScript"];

                if (o != null)
                    return (string)o;

                return "";
            }
            set
            {
                ViewState["OnCancelScript"] = value;
            }
        }


        [ExtenderControlEvent]
        [Category("Scripting")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), PersistenceMode(PersistenceMode.Attribute), NotifyParentProperty(true)]
        public virtual string Shown
        {
            get
            {
                object o = ViewState["Shown"];

                if (o != null)
                    return (string)o;

                return null;
            }
            set
            {
                ViewState["Shown"] = value;
            }
        }

        [ExtenderControlEvent]
        [Category("Scripting")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), PersistenceMode(PersistenceMode.Attribute), NotifyParentProperty(true)]
        public virtual string Showing
        {
            get
            {
                object o = ViewState["Showing"];

                if (o != null)
                    return (string)o;

                return null;
            }
            set
            {
                ViewState["Showing"] = value;
            }
        }

        [ExtenderControlEvent]
        [Category("Scripting")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), PersistenceMode(PersistenceMode.Attribute), NotifyParentProperty(true)]
        public virtual string Hiding
        {
            get
            {
                object o = ViewState["Hiding"];

                if (o != null)
                    return (string)o;

                return null;
            }
            set
            {
                ViewState["Hiding"] = value;
            }
        }

        [ExtenderControlEvent]
        [Category("Scripting")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), PersistenceMode(PersistenceMode.Attribute), NotifyParentProperty(true)]
        public virtual string Hidden
        {
            get
            {
                object o = ViewState["Hidden"];

                if (o != null)
                    return (string)o;

                return null;
            }
            set
            {
                ViewState["Hidden"] = value;
            }
        }


        #endregion

        /// <summary>
        /// Gets the dialog properties for the client side behavior.
        /// </summary>
        /// <value>The dialog properties for the client side behavior.</value>

        /// <summary>
        /// Gets the dialog property collection for the client side behavior.
        /// </summary>
        /// <value>The dialog property collection for the client side behavior.</value>
        [ExtenderControlProperty(true, true)]
        [ClientPropertyName("modalPopupProperties")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced)]
        public Dictionary<string, object> DialogPropertyCollection
        {
            get
            {
                if (_dialopProps == null)
                    _dialopProps = new Dictionary<string, object>();

                return _dialopProps;
            }
        }

        /// <summary>
        /// Gets or sets the service pass-thru data to be passed onwards to the service..
        /// </summary>
        /// <value>The service pass-thru data to be passed to the service.</value>
        [ExtenderControlProperty(true, true)]
        [ClientPropertyName("passThruData")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced)]
        public virtual Dictionary<string, string> ServicePassThruData
        {
            get
            {
                if (_servicePassThroughData == null)
                    _servicePassThroughData = new Dictionary<string, string>();

                return _servicePassThroughData;
            }
            private set
            {
                _servicePassThroughData = value;
            }
        }

        /// <summary>
        /// Gets the client state collection.
        /// </summary>
        /// <value>The client state collection.</value>
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced)]
        protected Dictionary<string, object> ClientStateCollection
        {
            get
            {
                if (_clientStates == null)
                    _clientStates = new Dictionary<string, object>();

                return _clientStates;
            }
            set
            {
                _clientStates = value;
            }
        }

        /// <summary>
        /// Gets the dialog behavior id.
        /// </summary>
        /// <value>The dialog behavior id.</value>
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced)]
        protected virtual string ModalPopupBehaviorId
        {
            get { return ClientID + "_modalPopupBehavior"; }
        }

        #endregion
    }
}
